﻿using RayDen.Library.Core.Primitives;
using RayDen.Library.Data.Imaging;
using RayDen.Library.Entity.Scene;

namespace RayDen.Library.Components.Surface.Spectral
{

    public abstract class SpectralBrdf
    {
        public SpectralDistribution Kd;
        public SpectralDistribution Ks;
        public SpectralDistribution Kr;
        public SpectralDistribution Kt;
        public SpectralDistribution Ke;
        public SpectralDistribution Ior;

        public MaterialInfo MaterialInfo;

        public void SetMaterialInfo(MaterialInfo mi)
        {
            if (mi == null)
            {
                var col = new RgbSpectrum(0.5f);
                this.Kd = ColorFactory.CreateRegularSpd(ref col, SpectrumType.Reflectance);
                return;
            }
            this.MaterialInfo = mi;
            this.Kd = ColorFactory.CreateRegularSpd(ref mi.Kd, SpectrumType.Reflectance);
            this.Ks = ColorFactory.CreateRegularSpd(ref mi.Ks, SpectrumType.Reflectance);
            this.Kr = ColorFactory.CreateRegularSpd(ref mi.Kr, SpectrumType.Reflectance);
            this.Kt = ColorFactory.CreateRegularSpd(ref mi.Kt, SpectrumType.Reflectance);
            this.Ke = ColorFactory.CreateRegularSpd(ref mi.Ke, SpectrumType.Reflectance);
        }

        public void SetDistributions(ref RgbSpectrum kd, ref RgbSpectrum ks, ref RgbSpectrum kr, ref RgbSpectrum ke, ref RgbSpectrum kt)
        {
            this.Kd = ColorFactory.CreateRegularSpd(ref kd, SpectrumType.Reflectance);
            this.Ks = ColorFactory.CreateRegularSpd(ref ks, SpectrumType.Reflectance);
            this.Kr = ColorFactory.CreateRegularSpd(ref kr, SpectrumType.Reflectance);
            this.Kt = ColorFactory.CreateRegularSpd(ref kt, SpectrumType.Reflectance);
            this.Ke = ColorFactory.CreateRegularSpd(ref ke, SpectrumType.Reflectance);
        }



        public abstract BrdfType Type { get; }
        public abstract bool IsDiffuse();
        public abstract bool IsSpecular();
        public abstract void F(ref Vector wo, ref Vector wi, ref Normal N, float lambda, out float fs);
        public abstract void Sample_f(ref Vector wo, ref Normal geoNormal, ref Normal shadeN, float lambda, ref SurfaceTextureData surfaceData,
                                      float u0, float u1, float u2, out BsdfSampleData result);
    }
}
